home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / slapstic.c < prev    next >
C/C++ Source or Header  |  2000-04-10  |  14KB  |  484 lines

  1. /*************************************************************************
  2.  
  3.   Atari Slapstic decoding helper
  4.  
  5. *************************************************************************
  6.  
  7. Slapstic FAQ - ver 0.2
  8. Frank Palazzolo
  9. 03/13/98
  10.  
  11. (Please send comments or corrections
  12.  to me at palazzol@home.com)
  13. ----------------------------------
  14.  
  15. 0) Credits:
  16.  
  17. I would like to thank the Motorola 68HC11 Evaluation
  18. Board.  Anything is possible with one of these :)
  19.  
  20. Special Thanks to:
  21. Aaron Giles, Mike Balfour, and Tim Lindquist, and the rest of
  22. the MAME Team
  23.  
  24. 1) What is a slapstic?
  25.  
  26. The slapstic was a chip made by Atari, which was used for
  27. bank-switching and security in some coin-operated video games.
  28.  
  29. 2) What games used one?
  30.  
  31. Empire Strikes Back
  32. Tetris
  33. Gauntlet
  34. Gauntlet II
  35. Marble Madness
  36. Peter Packrat
  37. Indiana Jones & the Temple of Doom
  38. Road Runner
  39. Road Blasters
  40. Paperboy
  41. APB
  42. 720 Degrees
  43. Super Sprint
  44. Championship Sprint
  45. Rampart
  46. Vindicators Part II
  47. Xybots
  48. Race Drivin'
  49.  
  50. 3) What is the pinout?
  51.  
  52. (It is a small 20 pin DIP package)
  53.  
  54. Pin #    Function
  55. ----------------------
  56. 1    A10 (I)
  57. 2    A11 (I)
  58. 3    A12 (I)
  59. 4    A13 (I)
  60. 5    A14 (I)
  61. 6    ~CS (I)
  62. 7    CLK (I)
  63. 8    +5V
  64. 9    BS1 (O)
  65. 10    BS0 (O)
  66. 11    Gnd
  67. 12    A1 (I)
  68. 13    A2 (I)
  69. 14    A3 (I)
  70. 15    A4 (I)
  71. 16    A5 (I)
  72. 17    A6 (I)
  73. 18    A7 (I)
  74. 19    A8 (I)
  75. 20    A9 (I)
  76.  
  77. 4) What did it do / How did it work?
  78.  
  79. This chip would sit on the address bus of a game CPU, and control which one
  80. of 4 possible banks of ROM would be selected into a given memory area based on
  81. a combination of accesses to that memory region.
  82.  
  83. Note1: All addresses are relative to the Slapstic's memory space, not necessarily the game's
  84. Note2: Reset Address = $0000 for all chips
  85. Note3: Addresses with a * next to them have been deduced, but not verified on real hardware
  86.  
  87. Chip #     Game                Bank Select Addresses      Disable Mask Ignore Mask   Secondary    Secondary Bank Select
  88.                                 (0)    (1)    (2)    (3)  (MS 10 bits) (LS 7 bits)    Enable    (0)    (1)    (2)    (3)
  89. ----------------------------------------------------------------------------------------------------------------------------
  90. 137412-101 ESB/Tetris          $0080, $0090, $00a0, $00b0    $1540        $00??       *$1dfe  *$1b5c *$1b5d *$1b5e *$1b5f
  91. 137412-103 Marble Madness      $0040, $0050, $0060, $0070    $34c0        $002d        $3d14   $3d24, $3d25, $3d26, $3d27
  92. 137412-104 Gauntlet            $0020, $0028, $0030, $0038    $3d90        $0069       *$3735  *$3764,*$3765,*$3766,*$3767
  93. 137412-105 Indiana Jones &     $0010, $0014, $0018, $001c    $35b0        $003d        $0092,  $00a4, $00a5, $00a6, $00a7
  94.            Paperboy
  95. 137412-106 Gauntlet II         $0008, $000a, $000c, $000e    $3da0        $002b       *$0052  *$0064,*$0065,*$0066,*$0067
  96. 137412-107 Peter Packrat &     $0018, $001a, $001c, $001e    $00a0        $006b        $3d52,  $3d64, $3d65, $3d66, $3d67
  97.            Xybots &
  98.            2-player Gauntlet &
  99.            720 Degrees
  100. 137412-108 Road Runner &       $0028, $002a, $002c, $002e    $0060        $001f        $????   $????, $????, $????, $????
  101.            Super Sprint
  102. 137412-109 Championship Sprint $0008, $000a, $000c, $000e    $3da0        $002b        $0052   $0064, $0065, $0066, $0067
  103. 137412-110 Road Blasters &     $0040, $0050, $0060, $0070    $34c0        $002d        $3d14   $3d24, $3d25, $3d26, $3d27
  104.            APB
  105. 137412-111 Pit Fighter         $0042, $0052, $0062, $0072    $???0        $000a
  106. 137412-116 Hydra &             $0044, $004c, $0054, $005c    $???0        $0069
  107.            Cyberball 2072 Tournament
  108. 137412-117 Race Drivin'
  109. 137412-118 Vindicators Part II $0014, $0034, $0054, $0074    $???0        $0002       *$1950  *$1958,*$1960,*$1968,*$1970
  110.            & Rampart
  111.  
  112. Surprisingly, the slapstic appears to have used DRAM cells to store
  113. the current bank.  After 5 or 6 seconds without a clock, the chip reverts
  114. to bank 3, with the chip reset (bank select addresses are enabled)
  115. Typically, the slapstic region is accessed often enough to cause a
  116. problem.
  117.  
  118. "Normal" operating mode of this chip is something like this:
  119.  
  120. Access $0000 (bank switching is now enabled for one switch)
  121. Access $xxxx ... (n times)
  122. Access $0008 (switch to bank 0 command)
  123. Access $1234 (During the access to location $1234,
  124.               the bank will be switched to 0, on the
  125.               rising edge of the clock pulse.
  126.  
  127. Note1: It appears that the access during the bank switch
  128.        comes from the new bank, but this may depend on
  129.        the processor inteface in question.
  130. Note2: The "reset" state of the part is equivalent to the part having
  131.        been accessed at location $0
  132.  
  133. The details of the state machine representing the chip are
  134. documented in the MAME code.
  135.  
  136. */
  137.  
  138.  
  139. #include <stdio.h>
  140. #include "driver.h"
  141.  
  142.  
  143. /*************************************
  144.  *
  145.  *    Structure of slapstic params
  146.  *
  147.  *************************************/
  148.  
  149. struct slapstic_params
  150. {
  151.     int reset;
  152.     int bank0, bank1, bank2, bank3;
  153.     int disable;
  154.     int ignore;
  155.     int senable;
  156.     int sbank0, sbank1, sbank2, sbank3;
  157. };
  158.  
  159.  
  160.  
  161. /*************************************
  162.  *
  163.  *    Constants
  164.  *
  165.  *************************************/
  166.  
  167. #define DISABLE_MASK 0x3ff0
  168. #define IGNORE_MASK  0x007f
  169. #define UNKNOWN      0xffff
  170.  
  171. enum state_type { ENABLED, DISABLED, IGNORE, SPECIAL };
  172.  
  173. #define LOG_SLAPSTIC 0
  174.  
  175.  
  176.  
  177. /*************************************
  178.  *
  179.  *    The master table
  180.  *
  181.  *************************************/
  182.  
  183. static struct slapstic_params slapstic_table[18] =
  184. {
  185.     /* 137412-101 ESB/Tetris */
  186.     { 0x0000, 0x0080, 0x0090, 0x00a0, 0x00b0, 0x1540,UNKNOWN, 0x1dfe, 0x1b5c, 0x1b5d, 0x1b5e, 0x1b5f },
  187.     /* 137412-102 ???? */
  188.     { 0x0000,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN },
  189.     /* 137412-103 Marble Madness */
  190.     { 0x0000, 0x0040, 0x0050, 0x0060, 0x0070, 0x34c0, 0x002d, 0x3d14, 0x3d24, 0x3d25, 0x3d26, 0x3d27 },
  191.     /* 137412-104 Gauntlet */
  192. /*    { 0x0000, 0x0020, 0x0028, 0x0030, 0x0038, 0x3d90, 0x0069, 0x3735, 0x3764, 0x3765, 0x3766, 0x3767 },*/
  193. /* EC990621 Gauntlet fix */
  194.     { 0x0000, 0x0020, 0x0028, 0x0030, 0x0038, 0x3da0, 0x0069, 0x3735, 0x3764, 0x3765, 0x3766, 0x3767 },
  195. /* EC990621 end of Gauntlet fix */
  196.     /* 137412-105 Indiana Jones/Paperboy */
  197.     { 0x0000, 0x0010, 0x0014, 0x0018, 0x001c, 0x35b0, 0x003d, 0x0092, 0x00a4, 0x00a5, 0x00a6, 0x00a7 },
  198.     /* 137412-106 Gauntlet II */
  199. /*    { 0x0000, 0x0008, 0x000a, 0x000c, 0x000e, 0x3da0, 0x002b, 0x0052, 0x0064, 0x0065, 0x0066, 0x0067 },*/
  200. /* NS990620 Gauntlet II fix */
  201.     { 0x0000, 0x0008, 0x000a, 0x000c, 0x000e, 0x3db0, 0x002b, 0x0052, 0x0064, 0x0065, 0x0066, 0x0067 },
  202. /* NS990620 end of Gauntlet II fix */
  203.     /* 137412-107 Peter Packrat/Xybots/2-player Gauntlet/720 Degrees */
  204. /*    { 0x0000, 0x0018, 0x001a, 0x001c, 0x001e, 0x00a0, 0x006b, 0x3d52, 0x3d64, 0x3d65, 0x3d66, 0x3d67 },*/
  205. /* NS990622 Xybots fix */
  206.     { 0x0000, 0x0018, 0x001a, 0x001c, 0x001e, 0x00b0, 0x006b, 0x3d52, 0x3d64, 0x3d65, 0x3d66, 0x3d67 },
  207. /* NS990622 end of Xybots fix */
  208.     /* 137412-108 Road Runner/Super Sprint */
  209.     { 0x0000, 0x0028, 0x002a, 0x002c, 0x002e, 0x0060, 0x001f,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN },
  210.     /* 137412-109 Championship Sprint */
  211.     { 0x0000, 0x0008, 0x000a, 0x000c, 0x000e, 0x3da0, 0x002b, 0x0052, 0x0064, 0x0065, 0x0066, 0x0067 },
  212.     /* 137412-110 Road Blasters/APB */
  213.     { 0x0000, 0x0040, 0x0050, 0x0060, 0x0070, 0x34c0, 0x002d, 0x3d14, 0x3d24, 0x3d25, 0x3d26, 0x3d27 },
  214.     /* 137412-111 Pit Fighter */
  215.     { 0x0000, 0x0042, 0x0052, 0x0062, 0x0072,UNKNOWN, 0x000a,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN },
  216.     /* 137412-112 ???? */
  217.     { 0x0000,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN },
  218.     /* 137412-113 ???? */
  219.     { 0x0000,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN },
  220.     /* 137412-114 ???? */
  221.     { 0x0000,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN },
  222.     /* 137412-115 ???? */
  223.     { 0x0000,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN },
  224.     /* 137412-116 Hydra/Cyberball 2072 Tournament */
  225.     { 0x0000, 0x0044, 0x004c, 0x0054, 0x005c,UNKNOWN, 0x0069,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN },
  226.     /* 137412-117 Race Drivin' */
  227.     { 0x0000,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN },
  228.     /* 137412-118 Vindicators II/Rampart */
  229. /*    { 0x0000, 0x0014, 0x0034, 0x0054, 0x0074,UNKNOWN, 0x0002, 0x1950, 0x1958, 0x1960, 0x1968, 0x1970 },*/
  230. /* EC990622 Rampart fix */
  231.     { 0x0000, 0x0014, 0x0034, 0x0054, 0x0074, 0x30e0, 0x0002, 0x1958, 0x1959, 0x195a, 0x195b, 0x195c },
  232. /* EC990622 end of Rampart fix */
  233. };
  234.  
  235.  
  236.  
  237. /*************************************
  238.  *
  239.  *    Statics
  240.  *
  241.  *************************************/
  242.  
  243. static struct slapstic_params *slapstic;
  244.  
  245. static enum state_type state;
  246. static INT8 next_bank;
  247. static INT8 extra_bank;
  248. static INT8 current_bank;
  249. static UINT8 version;
  250.  
  251. #if LOG_SLAPSTIC
  252.     static void slapstic_log(offs_t offset);
  253.     static FILE *slapsticlog;
  254. #else
  255.     #define slapstic_log(o)
  256. #endif
  257.  
  258.  
  259.  
  260. /*************************************
  261.  *
  262.  *    Initialization
  263.  *
  264.  *************************************/
  265.  
  266. void slapstic_init(int chip)
  267. {
  268.     /* only a small number of chips are known to exist */
  269.     if (chip < 101 || chip > 118)
  270.         return;
  271.  
  272.     /* set up a pointer to the parameters */
  273.     version = chip;
  274.     slapstic = slapstic_table + (chip - 101);
  275.  
  276.     /* reset the chip */
  277.     state = ENABLED;
  278.     next_bank = extra_bank = -1;
  279.  
  280.     /* the 111 and later chips seem to reset to bank 0 */
  281.     if (chip < 111)
  282.         current_bank = 3;
  283.     else
  284.         current_bank = 0;
  285. }
  286.  
  287.  
  288. void slapstic_reset(void)
  289. {
  290.     slapstic_init(version);
  291. }
  292.  
  293.  
  294.  
  295. /*************************************
  296.  *
  297.  *    Returns active bank without tweaking
  298.  *
  299.  *************************************/
  300.  
  301. int slapstic_bank(void)
  302. {
  303.     return current_bank;
  304. }
  305.  
  306.  
  307.  
  308. /*************************************
  309.  *
  310.  *    Call this before every access
  311.  *
  312.  *************************************/
  313.  
  314. int slapstic_tweak(offs_t offset)
  315. {
  316.     /* switch banks now if one is pending */
  317.     if (next_bank != -1)
  318.     {
  319.         current_bank = next_bank;
  320.         next_bank = -1;
  321.         extra_bank = -1;
  322.     }
  323.  
  324.     /* state machine */
  325.     switch (state)
  326.     {
  327.         /* ENABLED state: the chip has been activated and is ready for a bankswitch */
  328.         case ENABLED:
  329.             if ((offset & DISABLE_MASK) == slapstic->disable)
  330.             {
  331.                 state = DISABLED;
  332.                 /* NS990620 Gauntlet II fix */
  333.                 if (extra_bank != -1)
  334.                     next_bank = extra_bank;
  335.                 /* NS990620 end of Gauntlet II fix */
  336.             }
  337.             else if ((offset & IGNORE_MASK) == slapstic->ignore)
  338.             {
  339.                 state = IGNORE;
  340.             }
  341.             else if (offset == slapstic->bank0)
  342.             {
  343.                 state = DISABLED;
  344.                 if (extra_bank == -1)
  345.                     next_bank = 0;
  346.                 else
  347.                     next_bank = extra_bank;
  348.             }
  349.             else if (offset == slapstic->bank1)
  350.             {
  351.                 state = DISABLED;
  352.                 if (extra_bank == -1)
  353.                     next_bank = 1;
  354.                 else
  355.                     next_bank = extra_bank;
  356.             }
  357.             else if (offset == slapstic->bank2)
  358.             {
  359.                 state = DISABLED;
  360.                 if (extra_bank == -1)
  361.                     next_bank = 2;
  362.                 else
  363.                     next_bank = extra_bank;
  364.             }
  365.             else if (offset == slapstic->bank3)
  366.             {
  367.                 state = DISABLED;
  368.                 if (extra_bank == -1)
  369.                     next_bank = 3;
  370.                 else
  371.                     next_bank = extra_bank;
  372.             }
  373.             else if (offset == slapstic->reset)
  374.             {
  375.                 next_bank = -1;
  376.                 extra_bank = -1;
  377.             }
  378.             /* This is the transition which has */
  379.             /* not been verified on the HW yet */
  380.             else if (offset == slapstic->senable)
  381.             {
  382.                 state = SPECIAL;
  383.             }
  384.             break;
  385.  
  386.         /* DISABLED state: everything is ignored except a reset */
  387.         case DISABLED:
  388.             if (offset == slapstic->reset)
  389.             {
  390.                 state = ENABLED;
  391.                 next_bank = -1;
  392.                 extra_bank = -1;
  393.             }
  394.             break;
  395.  
  396.         /* IGNORE state: next access is interpreted differently */
  397.         case IGNORE:
  398.             if (offset == slapstic->senable)
  399.             {
  400.                 state = SPECIAL;
  401.             }
  402.             else
  403.             {
  404.                 state = ENABLED;
  405.             }
  406.             break;
  407.  
  408.         /* SPECIAL state: the special alternate bank switch override method is being used */
  409.         case SPECIAL:
  410.             if (offset == slapstic->sbank0)
  411.             {
  412.                 state = ENABLED;
  413.                 extra_bank = 0;
  414.             }
  415.             else if (offset == slapstic->sbank1)
  416.             {
  417.                 state = ENABLED;
  418.                 extra_bank = 1;
  419.             }
  420.             else if (offset == slapstic->sbank2)
  421.             {
  422.                 state = ENABLED;
  423.                 extra_bank = 2;
  424.             }
  425.             else if (offset == slapstic->sbank3)
  426.             {
  427.                 state = ENABLED;
  428.                 extra_bank = 3;
  429.             }
  430.             else if (offset == slapstic->reset)
  431.             {
  432.                 state = ENABLED;
  433.                 next_bank = -1;
  434.                 extra_bank = -1;
  435.             }
  436.             else
  437.             {
  438.                 state = ENABLED;
  439.             }
  440.             break;
  441.     }
  442.  
  443.     /* log this access */
  444.     slapstic_log(offset);
  445.  
  446.     /* return the active bank */
  447.     return current_bank;
  448. }
  449.  
  450.  
  451.  
  452. /*************************************
  453.  *
  454.  *    Debugging
  455.  *
  456.  *************************************/
  457.  
  458. #if LOG_SLAPSTIC
  459. static void slapstic_log(offs_t offset)
  460. {
  461.     if (!slapsticlog)
  462.         slapsticlog = fopen("slapstic.log", "w");
  463.     if (slapsticlog)
  464.     {
  465.         fprintf(slapsticlog, "%06X: %04X B=%d ", cpu_getpreviouspc(), offset, current_bank);
  466.         switch (state)
  467.         {
  468.             case ENABLED:
  469.                 fprintf(slapsticlog, "ENABLED\n");
  470.                 break;
  471.             case DISABLED:
  472.                 fprintf(slapsticlog, "DISABLED\n");
  473.                 break;
  474.             case SPECIAL:
  475.                 fprintf(slapsticlog, "SPECIAL\n");
  476.                 break;
  477.             case IGNORE:
  478.                 fprintf(slapsticlog, "IGNORE\n");
  479.                 break;
  480.         }
  481.     }
  482. }
  483. #endif
  484.